using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace CodeUtils
{
  public static class EncryptionUtils
  {
    public static byte[] GenerateKey()
    {
      RijndaelManaged provider = new RijndaelManaged();
      provider.GenerateKey();

      return provider.Key;
    }

    public static byte[] GenerateIV()
    {
      RijndaelManaged provider = new RijndaelManaged();
      provider.GenerateIV();

      return provider.IV;
    }

    public static string Decrypt(byte[] encryptedBytes, byte[] key, byte[] iv)
    {
      RijndaelManaged provider = new RijndaelManaged();

      MemoryStream ms = new MemoryStream();

      using (CryptoStream cryptoStream = new CryptoStream(ms, provider.CreateDecryptor(key, iv), CryptoStreamMode.Write))
      {
        cryptoStream.Write(encryptedBytes, 0, encryptedBytes.Length);
      }

      return Encoding.UTF8.GetString(ms.ToArray());
    }

    public static byte[] Encrypt(string value, byte[] key, byte[] iv)
    {
      RijndaelManaged provider = new RijndaelManaged();
      byte[] valueBytes = Encoding.UTF8.GetBytes(value);

      MemoryStream ms = new MemoryStream();

      using (CryptoStream cryptoStream = new CryptoStream(ms, provider.CreateEncryptor(key, iv), CryptoStreamMode.Write))
      {
        cryptoStream.Write(valueBytes, 0, valueBytes.Length);
      }

      return ms.ToArray();
    }

  }
  public class Encryption
  {
      #region Class Constructor

      public Encryption()
      {

      }

      #endregion
      #region Class Static Methods
      /// <summary>
      /// This Function is used to Generate Key      
      /// </summary>
      /// <returns>Byte Array type that hold the Key</returns>
      private static byte[] GenerateKey()
      {
          //TripleDESCryptoServiceProvider tDes = new TripleDESCryptoServiceProvider();
          //tDes.GenerateKey();
          //_DecryptionKey = tDes.Key;
          return new byte[] { 137, 241, 181, 79, 71, 224, 162, 36, 42, 198, 36, 4, 89, 100, 242, 89, 49, 180, 203, 213, 76, 230, 95, 37 };
      }
      /// <summary>
      /// This Function is used to Encrypt the password        
      /// </summary>
      /// <param name="strPassword">String Type Parameter that hold the password in Plain Text</param>
      /// <returns>String Type Parameter that hold the password in Encrypted Form</returns>
      public static string EncryptPassword(string strPassword)
      {
          byte[] _DecryptionKey = GenerateKey();

          System.Text.UnicodeEncoding ue = new System.Text.UnicodeEncoding();
          byte[] uePassword = ue.GetBytes(strPassword);
          byte[] RetVal = null;

          // TripleDes Encrypt format
          TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider();

          tripleDes.Key = _DecryptionKey;
          tripleDes.IV = new byte[8];

          MemoryStream mStreamEnc = new MemoryStream();
          CryptoStream cryptoStream = new CryptoStream(mStreamEnc, tripleDes.CreateEncryptor(), CryptoStreamMode.Write);

          cryptoStream.Write(uePassword, 0, uePassword.Length);
          cryptoStream.FlushFinalBlock();
          RetVal = mStreamEnc.ToArray();
          cryptoStream.Close();

          return Convert.ToBase64String(RetVal, 0, RetVal.GetLength(0));

      }
      /// <summary>
      /// This Function is used to Decrypt the password        ///
      /// </summary>
      /// <param name="strPWD">String Type parameter that holds the User Password in Encrypted Form</param>
      /// <returns>String Type Parameter that hold the password in Plain Text</returns>
      public static string DecryptPassword(string strPWD)
      {
          byte[] _DecryptionKey = GenerateKey();

          byte[] StoredPassword = Convert.FromBase64String(strPWD);

          System.Text.UnicodeEncoding ue = new System.Text.UnicodeEncoding();
          string RetVal = null;

          TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider();

          tripleDes.Key = _DecryptionKey;
          tripleDes.IV = new byte[8];

          CryptoStream cryptoStream = new CryptoStream(new MemoryStream(StoredPassword), tripleDes.CreateDecryptor(), CryptoStreamMode.Read);
          MemoryStream msPasswordDec = new MemoryStream();
          int BytesRead = 0;

          byte[] Buffer = new byte[32];
          while ((BytesRead = cryptoStream.Read(Buffer, 0, 32)) > 0)
          {
              msPasswordDec.Write(Buffer, 0, BytesRead);
          }
          cryptoStream.Close();

          RetVal = ue.GetString(msPasswordDec.ToArray());
          msPasswordDec.Close();

          return RetVal;
      }
      #endregion
  }
}